home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 4 / Atari Forever 4.zip / Atari Forever 4.iso / SERIE_AI / AI_018 / POVRAY3.LZH / 3DSPOV18 / SOURCE / 3DSANI.C < prev    next >
C/C++ Source or Header  |  1995-05-20  |  6KB  |  289 lines

  1. #define __GNUC__
  2.  
  3. #include <stdio.h>
  4. #include "portab.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <math.h>
  8. /*
  9. #include <values.h>
  10. */
  11. char filename[80];
  12. char vuename[80];
  13. char tplname[80];
  14. char outname[80];
  15. int  fstart;
  16. int  fend;
  17. int  fstep;
  18.  
  19. void process_args (int argc, char *argv[]);
  20. void read_vue (char *fname, int *start, int *end);
  21. void add_ext (char *fname, char *ext, int force);
  22. void abortmsg (char *msg, int exit_code);
  23. char *after (char *str, char *target);
  24. char lookahead (FILE *f);
  25. char upcase (char ch);
  26.  
  27.  
  28. int main (int argc, char *argv[])
  29. {
  30.     FILE *tpl, *out;
  31.     char fstring[] = "%03d";
  32.     char ch;
  33.     int  frame, digits, i;
  34.  
  35.     /* Handle the command line args */
  36.     process_args (argc, argv);
  37.  
  38.     /* Get the start/end frame numbers from the .vue file */
  39.     read_vue (vuename, &fstart, &fend);
  40.  
  41.     if (fstart > fend)
  42.     abortmsg ("No frames generated.", 1);
  43.  
  44.     digits = (fend < 1) ? 1 : (floor(log10(fend)) + 1);
  45.  
  46.     out = fopen (outname, "w");
  47.     if (out == NULL) {
  48.     printf ("Unable to open output file '%s'", outname);
  49.     exit(1);
  50.     }
  51.  
  52.     printf ("Output to: %s\n", outname);
  53.  
  54.     for (frame = fstart; frame <= fend; frame = frame + fstep) {
  55.     tpl = fopen (tplname, "r");
  56.  
  57.     if (tpl == NULL) {
  58.         printf ("Unable to open template file '%s'\n", tplname);
  59.         exit(1);
  60.     }
  61.  
  62.     while (1) {
  63.         ch = getc (tpl);
  64.  
  65.         if (feof(tpl))
  66.         break;
  67.  
  68.         if (ch == '$') {
  69.         if (lookahead(tpl) == '#' && (strlen(filename) + digits > 8)) {
  70.             for (i = 0; i < 8 - digits; i++)
  71.             putc (filename[i], out);
  72.         }
  73.         else
  74.             fprintf (out, "%s", filename);
  75.         }
  76.         else if (ch == '#') {
  77.         fstring[2] = '0' + digits;
  78.         fprintf (out, fstring, frame);
  79.         }
  80.         else
  81.         putc (ch, out);
  82.     }
  83.  
  84.     fclose (tpl);
  85.     }
  86.  
  87.     fclose (out);
  88.  
  89.     return 0;
  90. }
  91.  
  92.  
  93.  
  94. void process_args (int argc, char *argv[])
  95. {
  96.     int i;
  97.  
  98.     printf("\n\n3DS2POV Animation Utility\n");
  99.     printf ("\n");
  100.  
  101.     if (argc < 2) {
  102.     printf ("Usage: 3dsani inputfile [options]\n\n");
  103.     printf ("Options: -a<filename> - Specifies name of the 3ds animation (.vue) file\n");
  104.     printf ("         -t<filename> - Specifies name of the template (.tpl) file\n");
  105.     printf ("         -o<filename> - Specifies name of the output (.bat) file\n");
  106.     printf ("         -snnn        - Start animation at frame nnn\n");
  107.     printf ("         -ennn        - End animation at frame nnn\n");
  108.     printf ("         -pnnn        - Render every nnn'th frane\n");
  109.     printf ("\nex. 3dsani ruby -aruby.vue -tani.tpl -oruby.bat -s0 -e10\n\n");
  110.     exit(1);
  111.     }
  112.  
  113.     strcpy (filename, "");
  114.     strcpy (vuename, "");
  115.     strcpy (tplname, "");
  116.     strcpy (outname, "");
  117.     fstart = -1;
  118.     fend   = -1;
  119.     fstep  =  1;
  120.  
  121.     for (i = 1; i < argc; i++) {
  122.     if (argv[i][0] == '-' || argv[i][0] == '/') {
  123.         switch (upcase(argv[i][1])) {
  124.         case 'A': strcpy (vuename, &argv[i][2]);
  125.               break;
  126.  
  127.         case 'T': strcpy (tplname, &argv[i][2]);
  128.               break;
  129.  
  130.         case 'O': strcpy (outname, &argv[i][2]);
  131.               break;
  132.  
  133.         case 'S': if (argv[i][2] != '\0')
  134.                   fstart = atoi (&argv[i][2]);
  135.               break;
  136.  
  137.         case 'E': if (argv[i][2] != '\0')
  138.                   fend = atoi (&argv[i][2]);
  139.               break;
  140.  
  141.         case 'P': if (argv[i][2] != '\0') {
  142.                   fstep = atoi (&argv[i][2]);
  143.  
  144.                   if (fstep < 1)
  145.                   fstep = 1;
  146.               }
  147.               break;
  148.  
  149.         default : printf ("\nInvalid option -%c\n", argv[i][1]);
  150.               exit (1);
  151.         }
  152.     }
  153.     else if (strlen (filename) == 0) {
  154.         strcpy (filename, argv[i]);
  155.         add_ext (filename, "", 1);
  156.     }
  157.     else
  158.         abortmsg ("Too many file names specified.", 1);
  159.     }
  160.  
  161.     if (strlen (filename) == 0)
  162.     abortmsg ("No file name specified", 1);
  163.  
  164.     if (strlen(vuename) == 0) {
  165.     strcpy (vuename, filename);
  166.     add_ext (vuename, "vue", 1);
  167.     }
  168.  
  169.     if (strlen (tplname) == 0) {
  170.     strcpy (tplname, filename);
  171.     add_ext (tplname, "tpl", 1);
  172.     }
  173.  
  174.     if (strlen (outname) == 0) {
  175.     strcpy (outname, filename);
  176.     add_ext (outname, "bat", 1);
  177.     }
  178.  
  179.     add_ext (vuename, "vue", 0);
  180.     add_ext (tplname, "tpl", 0);
  181.     add_ext (outname, "bat", 0);
  182. }
  183.  
  184. /* Read the start/end frame numbers from the .vue file */
  185. void read_vue (char *fname, int *start, int *end)
  186. {
  187.     FILE *f;
  188.     char string[256];
  189.     int  fmin, fmax, frame;
  190.  
  191.     f = fopen (fname, "r");
  192.  
  193.     if (f != NULL) {
  194.     fmin = +MAXINT;
  195.     fmax = -MAXINT;
  196.  
  197.     while (fgets (string, 256, f) != NULL) {
  198.         if (strstr (string, "frame") == string) {
  199.         frame = atoi (after (string, "frame"));
  200.  
  201.         if (frame < fmin)  fmin = frame;
  202.         if (frame > fmax)  fmax = frame;
  203.         }
  204.     }
  205.  
  206.     if (*start < 0 && fmin != +MAXINT)
  207.         *start = fmin;
  208.  
  209.     if (*end < 0 && fmax != -MAXINT)
  210.         *end = fmax;
  211.  
  212.     fclose(f);
  213.     }
  214.  
  215.     if (*start < 0)
  216.     abortmsg ("No start frame specified", 1);
  217.  
  218.     if (*end < 0)
  219.     abortmsg ("No end frame specified", 1);
  220.  
  221.     printf ("Generating frames %d through %d", *start, *end);
  222.  
  223.     if (fstep > 1)
  224.     printf (" (every %d frames)", fstep);
  225.  
  226.     printf ("\n");
  227. }
  228.  
  229.  
  230. void add_ext (char *fname, char *ext, int force)
  231. {
  232.     int i;
  233.  
  234.     for (i = 0; i < strlen(fname); i++)
  235.     if (fname[i] == '.') break;
  236.  
  237.     if (fname[i] == '\0' || force) {
  238.     if (strlen(ext) > 0)
  239.         fname[i++] = '.';
  240.  
  241.     strcpy (&fname[i], ext);
  242.     }
  243. }
  244.  
  245.  
  246. void abortmsg (char *msg, int exit_code)
  247. {
  248.     printf ("\n%s\n", msg);
  249.     exit (exit_code);
  250. }
  251.  
  252.  
  253. char *after (char *str, char *target)
  254. {
  255.     static char result[256];
  256.     char   *search;
  257.  
  258.     search = strstr (str, target);
  259.  
  260.     if (search == NULL)
  261.     strncpy (result, "", 256);
  262.     else
  263.     strncpy (result, search + strlen(target), 256);
  264.  
  265.     result[255] = '\0';
  266.  
  267.     return result;
  268. }
  269.  
  270. /* Peek at the next character in the file */
  271. char lookahead (FILE *f)
  272. {
  273.     char ch;
  274.  
  275.     ch = getc (f);
  276.     ungetc (ch, f);
  277.  
  278.     return ch;
  279. }
  280.  
  281.  
  282. char upcase (char c)
  283. {
  284.     if (c >= 'a' && c <= 'z')
  285.     c = c - 'a' + 'A';
  286.  
  287.     return c;
  288. }
  289.